package person.bangbang.im.Androidgin.UI;

import person.bangbang.im.Androidgin.Androidgin;
import person.bangbang.im.Androidgin.AndroidginPref;
import person.bangbang.im.Androidgin.AndroidginService;
import person.bangbang.im.Androidgin.R;
import person.bangbang.im.Androidgin.Framework.Account;
import person.bangbang.im.Androidgin.Framework.Accounts;
import person.bangbang.im.Androidgin.Framework.Protocol;
import person.bangbang.im.Androidgin.Framework.ProtocolSpec;
import person.bangbang.im.Androidgin.Framework.StatusType;
import person.bangbang.im.Androidgin.Util.Log;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.IBinder;
import android.preference.PreferenceManager;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.Toast;
/**
 * Login activity for ANdroidgin.
 * be sure all initiation work has been done before enter this.
 */
public class Login extends Activity {
	private static String TAG = "Androidgin.Login";
	
	private static String PROTOCOL_INDEX= "protocol_index";
	private static String USER_NAME = "user_name";
	private static String USER_PASSWARD = "user_passward";
	private static String REM_PASSWARD = AndroidginPref.KEY_REM;
	private static String STATE_INDEX = "state_index";
	
	private int mProtocolIndex;
	private String mUserName;
	private String mPassward;
	private boolean mRemPassward;
	private int mLoginStateIndex;
	
	private Spinner mSpinnPro;
	private Spinner mSpinnSta;
	
	private Account mAcc = null;
	
	private ProtocolSpec mSpec[] ;
	private ServiceConnection mConn = new ServiceConnection(){
		public void onServiceConnected(ComponentName comp, IBinder service) {
			mService = ((AndroidginService.LocalBinder)service).getService();
			init();
		}
		public void onServiceDisconnected(ComponentName comp) {
//			cleanUp();
		}
		
	};
	// the service must give us the support protocols and 
	// give the status of any protocols supported.
	private AndroidginService mService = null;
	
	private Protocol.OnLoginProcess mLoginProcess = new Protocol.OnLoginProcess() {

		public void onLoginErr(int code, String msg) {
			// TODO Auto-generated method stub
			
		}

		public void onLoginStep(int which_step, int total_steps, String msg) {
			Log.d(TAG, "Login..");
			Log.d(TAG, "Login at " + which_step + " step " + "(" + total_steps + ")" + "\n" + msg);
			
			say("Login at " + which_step + " step " + "(" + total_steps + ")" + "\n" + msg);
			if (which_step == total_steps) {
				mAcc.unRegOnLoginProcessListener(mLoginProcess);
				mService.setState(AndroidginService.STATE_SIGNNED);
				setResult(Androidgin.LOGIN_OK);
				
				unbindService(mConn);
				finish();
			}
		}
		
	};
	@Override
	protected void onResume() {
		// TODO Auto-generated method stub
		super.onResume();
		restoreState();

	}
	@Override
	protected void onPause() {
		// TODO Auto-generated method stub
		super.onPause();
	}
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.login);
		
		mSpinnPro = ((Spinner)findViewById(R.id.login_protocol));
		mSpinnSta = ((Spinner)findViewById(R.id.login_status));
		bindService(new Intent(Login.this, AndroidginService.class), mConn, BIND_AUTO_CREATE);
	}
	
	// set listener???
	private void init(){
		mSpec = mService.getSupportProtocl();
		
		// TODO get the support protocols dynamically
		ArrayAdapter adapter = new ProtocolAdapter(getApplicationContext(),
													android.R.layout.simple_spinner_item,
                                                    mSpec);
		adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
		
		mSpinnPro.setAdapter(adapter);
		mSpinnPro.setOnItemSelectedListener(
				new AdapterView.OnItemSelectedListener() {
					public void onItemSelected(AdapterView<?> parent, View view,
							int position, long id) {
							// update the status spinner
							updateStatusSpinner(position);
					}

					public void onNothingSelected(AdapterView<?> parent) {
						// TODO Auto-generated method stub
						
					}
				});
		updateStatusSpinner((int)mSpinnPro.getSelectedItemId());
		
		((Button)findViewById(R.id.login_button)).setOnClickListener(
				new View.OnClickListener() {
					public void onClick(View v) {
						// TODO Auto-generated method stub
						doLogin();
					}
				});
		((Button)findViewById(R.id.cancel_button)).setOnClickListener(
				new View.OnClickListener() {
					public void onClick(View v) {
						// TODO Auto-generated method stub
						doCancel();
					}
				});		
	}
	
	private void updateStatusSpinner(int postion) {
		ArrayAdapter statusAdapter = new StatusAdapter(this,
				android.R.layout.simple_spinner_item,
				mSpec[postion].getStatus()
		        );
				((Spinner)findViewById(R.id.login_status)).setAdapter(statusAdapter);
	}
	private boolean hasLogin() {
		// TODO: check the duplicate state.
		return false;
	}
	
	private void doLogin(){
		getState();
		
		if (hasLogin()) {
			Toast.makeText(getApplicationContext(), "this account has login!!! has another one", Toast.LENGTH_LONG);
			return;
		}
		
		// ooxx is OOP, this is stupid.
//		if (mUserName  == "" || mPassward  == "") {
		if (mUserName.equals("") || mPassward.equals("")) {
			say("tht name or passward is(are) empty, please fill it ^_^");
			return;
		}
		
		saveState();
		
		mAcc = Accounts.getInstance().createAccount(mSpec[(int)mSpinnPro.getSelectedItemId()].getId(),
				                              mUserName,
				                              mPassward,
				                              (StatusType)mSpinnSta.getSelectedItem());
		
		if (null != mAcc) {
			
			mAcc.regOnLoginProcessListener(mLoginProcess);
			mAcc.signon();
		} else {
			say("you have login in as this account @ what are U doing @_@");
		}
	}
	private void doCancel(){
		setResult(Androidgin.LOGIN_CANCEL);
		unbindService(mConn);
		finish();
	}
	
	
	/**
	 * write all states to specific vars (names, passwards,...)
	 */
	private void getState(){
		mProtocolIndex = (int) mSpinnPro.getSelectedItemId();
		mUserName = ((EditText)findViewById(R.id.username)).getText().toString();
		mPassward = ((EditText)findViewById(R.id.password)).getText().toString();
		mRemPassward = ((CheckBox)findViewById(R.id.remember)).isChecked();
		mLoginStateIndex = (int) mSpinnSta.getSelectedItemId();
	}
	
	private void saveState() {
		getState();
		
		// FIXME del this when implement by xml file.
		String protocolId = (((Spinner)findViewById(R.id.login_protocol)).getSelectedItem()).toString();
//		mLoginAccounts.add(mUserName + "#" +protocolId);
		
//		SharedPreferences pref = getSharedPreferences(PREF, 0);// MODE_PRIVATE
		// Corporation with Preference Framework
		SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
		SharedPreferences.Editor editor = pref.edit();
		editor.putInt(PROTOCOL_INDEX, mProtocolIndex);
		editor.putString(USER_NAME, mUserName);
		if (mRemPassward) {
			editor.putString(USER_PASSWARD, mPassward);
		} else {
			editor.putString(USER_PASSWARD, "");
		}
		editor.putBoolean(REM_PASSWARD, mRemPassward);
		editor.putInt(STATE_INDEX, mLoginStateIndex);
		editor.commit();
	}
	
	private void restoreState() {
//		SharedPreferences pref = getSharedPreferences(PREF, 0);// MODE_PRIVATE
		SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());

		if (null == pref) {
			return;
		}
		mSpinnPro.setSelection(pref.getInt(PROTOCOL_INDEX, 0));
		((EditText)findViewById(R.id.username)).setText(pref.getString(USER_NAME, ""));
		((EditText)findViewById(R.id.password)).setText(pref.getString(USER_PASSWARD, ""));
		((CheckBox)findViewById(R.id.remember)).setChecked(pref.getBoolean(REM_PASSWARD, true));
		mSpinnSta.setSelection(pref.getInt(STATE_INDEX, 0));
	}
	

	// keep this func in the bottom.
	private void say(String text) {
		Toast.makeText(getApplicationContext(), text, Toast.LENGTH_SHORT).show();
	}
}
